package com.ruoyi.framework.interceptor;

import com.ruoyi.common.exception.Web.AuthTokenException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.interceptor.annotation.IgnoreAuth;
import com.ruoyi.project.WebMoudle.WxUser.domain.WxUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

/**
 * 权限token验证，网页前端调用后台接口校验是否授权
 * 此拦截器作用方式是判断请求头里面的token是否过期或者是否有token数据判断出是否需要拦截进行跳转到登录重新登录
 * @author yangz
 * @email 17866232944@163.com
 */
public class AuthorizationInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    public static final String LOGIN_USER_KEY = "LOGIN_USER_KEY";
    public static final String LOGIN_TOKEN_KEY="X-Nideshop-Token";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler){
        //支持跨域请求
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with,X-Nideshop-Token,X-URL-PATH");
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));

        //这里涉及到一个自定义注解，忽略验证的功能
        IgnoreAuth annotation;
        if (handler instanceof HandlerMethod){
            annotation=((HandlerMethod)handler).getMethodAnnotation(IgnoreAuth.class);
        }else {
            return true;
        }

        //如果有@IgnoreAuth注解，则不验证token
        if (annotation!=null){
            //放行
            return true;
        }

        //从header中获取token
        String token=request.getHeader(LOGIN_TOKEN_KEY);

        if (StringUtils.isBlank(token)) {
            token = request.getParameter(LOGIN_TOKEN_KEY);

        }

        //token为空
        if (StringUtils.isBlank(token)) {
            throw new AuthTokenException("请先登录", 401);
        }

        //根据token在redis中查询，看是否有用户信息以及是否在有效期内
        WxUser userInfo=(WxUser) redisTemplate.opsForValue().get(token);
        if (userInfo!=null){
//            更新redis中用户登录有效期
            request.setAttribute(LOGIN_USER_KEY, userInfo.getId());
            redisTemplate.expire(token,15,TimeUnit.DAYS);//延长15天
        }else {
//            有token,但是失效了
            throw new AuthTokenException("登录失效", 401);
        }
        return true;
    }

}















